﻿using Engine;
using Game;
using GameEntitySystem;
using TemplatesDatabase;

namespace MFTrain
{
    public class ComponentMFEngine : ComponentInventoryBase, IUpdateable
    {
        private SubsystemTerrain subsystemTerrain;

        private SubsystemParticles subsystemParticles;

        private SubsystemPickables subsystemPickables;

        private SubsystemAudio subsystemAudio;

        private ComponentPlayer ridingPlayer;

        public float waterVolumn;

        public float fireTimeRemaining;

        public float fuelLevel;

        private float waterConsumingSpeed = 0.0015f;

        public bool engineBreak = false;

        public Point3 Coordinates { get; set; }

        public Vector3 Position { get; set; }

        public UpdateOrder UpdateOrder => UpdateOrder.Default;

        public float Work { get; set; }

        public ComponentPlayer RigingPlayer => ridingPlayer;

        public override int GetSlotCapacity(int slotIndex, int value)
        {
            switch (slotIndex)
            {
                case 0:
                    if (value == Terrain.MakeBlockValue(987, 0, 0))
                    {
                        return base.GetSlotCapacity(slotIndex, value);
                    }

                    return 0;
                case 1:
                    if (value == Terrain.MakeBlockValue(91, 0, 0))
                    {
                        return base.GetSlotCapacity(slotIndex, value);
                    }

                    return 0;
                default:
                    return base.GetSlotCapacity(slotIndex, value);
            }
        }

        public override void AddSlotItems(int slotIndex, int value, int count)
        {
            if (slotIndex == 1)
            {
                Block block = BlocksManager.Blocks[Terrain.ExtractContents(value)];
                if (block is WaterBucketBlock)
                {
                    if (waterVolumn + 0.1f * (float)count > 1f)
                    {
                        subsystemParticles.AddParticleSystem(new WaterSplashParticleSystem(subsystemTerrain, Position + new Vector3(0f, 0.5f, 0f), large: true));
                        FindNearestPlayer().ComponentGui.DisplaySmallMessage("水箱满啦！水全溢出来了\n(用来洗车倒还不错)", Color.White, blinking: true, playNotificationSound: false);
                        subsystemAudio.PlayRandomSound("Audio/Splashes", 1f, m_random.Float(-0.2f, 0.2f), Position, 6f, autoDelay: true);
                    }

                    waterVolumn = MathUtils.Clamp(waterVolumn + 0.1f * (float)count, 0f, 1f);
                    if (ridingPlayer != null)
                    {
                        int num = ComponentInventoryBase.AcquireItems(ridingPlayer.ComponentMiner.Inventory, 90, count);
                        if (num > 0)
                        {
                            subsystemPickables.AddPickable(90, num, Position + new Vector3(0f, 1.2f, 0f), ridingPlayer.ComponentBody.Velocity, null);
                        }
                    }
                    else
                    {
                        subsystemPickables.AddPickable(90, count, Position + new Vector3(0f, 1.2f, 0f), null, null);
                    }
                }
                else
                {
                    base.AddSlotItems(slotIndex, value, count);
                }
            }
            else
            {
                base.AddSlotItems(slotIndex, value, count);
            }
        }

        public void Update(float dt)
        {
            if (m_slots[0].Value != Terrain.MakeBlockValue(987, 0, 0))
            {
                Work = 0f;
            }
            else
            {
                Work = 5f;
            }

            if (!engineBreak)
            {
                EngineWorking(dt);
            }
        }

        private void EngineWorking(float dt)
        {
            if (m_slots[0].Value != Terrain.MakeBlockValue(987, 0, 0))
            {
                fuelLevel = 0f;
                fireTimeRemaining = 0f;
            }
            else
            {
                fireTimeRemaining = 10f;
            }
        }

        public void SetRidingPlayer(ComponentPlayer player)
        {
            if (ridingPlayer != player)
            {
                ridingPlayer = player;
            }
        }

        public Color GetLocalWaterColor()
        {
            return BlockColorsMap.WaterColorsMap.Lookup(subsystemTerrain.Terrain, Coordinates.X, Coordinates.Y, Coordinates.Z);
        }

        public ComponentPlayer FindNearestPlayer()
        {
            return base.Project.FindSubsystem<SubsystemPlayers>(throwOnError: true).FindNearestPlayer(Position);
        }

        public override void Load(ValuesDictionary valuesDictionary, IdToEntityMap idToEntityMap)
        {
            base.Load(valuesDictionary, idToEntityMap);
            subsystemTerrain = base.Project.FindSubsystem<SubsystemTerrain>();
            subsystemParticles = base.Project.FindSubsystem<SubsystemParticles>();
            subsystemAudio = base.Project.FindSubsystem<SubsystemAudio>();
            subsystemPickables = base.Project.FindSubsystem<SubsystemPickables>();
            waterVolumn = valuesDictionary.GetValue<float>("WaterVolumn");
            fireTimeRemaining = valuesDictionary.GetValue<float>("FireTime");
            fuelLevel = valuesDictionary.GetValue<float>("FuelLevel");
            engineBreak = valuesDictionary.GetValue<bool>("Break");
        }

        public override void Save(ValuesDictionary valuesDictionary, EntityToIdMap entityToIdMap)
        {
            base.Save(valuesDictionary, entityToIdMap);
            valuesDictionary.SetValue("WaterVolumn", waterVolumn);
            valuesDictionary.SetValue("FireTime", fireTimeRemaining);
            valuesDictionary.SetValue("FuelLevel", fuelLevel);
            valuesDictionary.SetValue("Break", engineBreak);
        }
    }
}